#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@Desc    :   德国汉莎航空
"""
import copy
from typing import Union, Dict, List

from src.enum.result import FlightStatusEnum
from parsel import Selector
from datetime import datetime, timedelta
from selenium.webdriver.common.by import By

from src import settings
from src.exception import NonDataException
from src.model.air_waybill import AwbCargoEvent,AwbFlight,AwbResult
from src.plugin import AwbSpiderBase
from src.util import common_util
from src.util.browser_chrome import BrowserDriver


class AirWaybillSpider(AwbSpiderBase):
    def __init__(self, *args):
        self.key = "020"
        super().__init__(*args)

    def __research_awb(self,slm_driver,waybill,idx) ->bool:
        if idx > 3:
            return False
        awb_error_container = slm_driver.wait_element_by_xpath('//div[@class="icp-etr-awbdetails-error-container"]', wait_time=5)
        if awb_error_container is not None:
            if awb_error_container.text is not None or common_util.formatter_html_text(awb_error_container.text) != "":
                raise NonDataException()
        awb_content =slm_driver.wait_element_by_xpath('//div[@class="awbDetailscontent"]/div[1]/div[1]/strong', wait_time=5)
        if awb_content is not None:
            awb_content = awb_content.text
            if awb_content.find("AWB") != -1 and awb_content.find(waybill) != -1:
                return True
            slm_driver.find_element_by_xpath(
                '//input[@id="_etrkawbdetails_WAR_etrkportlet_awbNumber_1"]').send_keys(waybill)
            common_util.sleep_short_random()
            search_btn = slm_driver.find_element_by_xpath(
                '//button[@id="_etrkawbdetails_WAR_etrkportlet_awbSearchBtn"]')
            search_btn.click()
            common_util.sleep_short_random()
            return self.__research_awb(slm_driver,waybill,idx + 1)
        else:
            raise NonDataException()

    def crawling_page(self,waybills: str,proxy=None,idx: int = 0) -> Union[None, Dict, Selector]:
        t_waybill_num = waybills
        if len(waybills) != 11:
            t_waybill_num = t_waybill_num.replace("-", "")
        t_waybill_end = t_waybill_num[3: len(t_waybill_num)]
        with BrowserDriver(proxy=proxy,show_auto_test=False) as driver:
            url = "https://www.lufthansa-cargo.com/en/eservices/etracking/awb-details"
            driver.get(url)
            common_util.sleep_short_random()
            user_centrics_root = driver.wait_element_by_id('usercentrics-root',wait_time=10)
            shadow_root = user_centrics_root.shadow_root
            if shadow_root is not None:
                deny_accept_btn_list = shadow_root.find_elements(by=By.CSS_SELECTOR,value="button.sc-dcJsrY")
                if deny_accept_btn_list is not None and len(deny_accept_btn_list) == 2:
                    deny_accept_btn_list[1].click()
            self.__research_awb(driver, t_waybill_end, idx)
            return driver.to_selector()

    def pick_base_info(self, data) -> AwbResult:
        awb_info = copy.deepcopy(AwbResult())
        awb_info_div = data.xpath('//div[@class="awbDetailscontent"]/div[3]')
        awb_col_list = awb_info_div.xpath('div[1]/div/div')
        for awb_col in awb_col_list:
            col_title = common_util.formatter_html_text(awb_col.xpath('h6/text()').get())
            if col_title == "Origin":
                awb_info.orig_airport = common_util.formatter_html_text(awb_col.xpath('div/text()').get().split("(")[0])
            elif col_title == "Destination":
                awb_info.dest_airport = common_util.formatter_html_text(awb_col.xpath('div/text()').get().split("(")[0])
            elif col_title == "Product":
                awb_info.goods_desc = common_util.formatter_html_text(awb_col.xpath('div/text()').get())
            elif col_title == "Pieces":
                pieces = common_util.formatter_html_text(awb_col.xpath('div/text()').get())
                if pieces.isnumeric():
                    awb_info.total_pieces = int(pieces)
            elif col_title == "Actual weight":
                awb_info.total_weight = common_util.formatter_html_text(awb_col.xpath('div/text()').get())
        return awb_info

    def pick_flight_list(self, data, s_airport, e_airport) -> List[AwbFlight]:
        flight_row_list = data.xpath('//table[@id="_etrkawbdetails_WAR_etrkportlet_latestBookingFlightsTableContainer"]/tbody/tr')
        flight_list: List[AwbFlight] = []
        i = 0
        for flight_row in flight_row_list:
            flight_node = copy.deepcopy(AwbFlight())
            flight_col_list = flight_row.xpath('td')
            i=i+1
            flight_node.flight_no = i
            # 信息
            origin_airport = flight_col_list[0].xpath('.//text()').get()
            flight_node.s_airport = origin_airport.split("(")[0].strip()
            dest_airport = flight_col_list[1].xpath('.//text()').get()
            flight_node.e_airport = dest_airport.split("(")[0].strip()
            flight_node.flight_number = flight_col_list[2].xpath('.//text()').get()
            flight_node.flight_date = flight_col_list[3].xpath('text()').get()
            pieces = flight_col_list[4].xpath('text()').get()
            if pieces.isnumeric():
                flight_node.pieces = pieces
            flight_node.weight = flight_col_list[5].xpath('text()').get()
            flight_volume = flight_col_list[6].xpath('.//text()').getall()
            flight_node.volume = common_util.formatter_html_text(flight_volume[0]) + flight_volume[1]
            flight_node.flight_status = FlightStatusEnum.UN_TAKE_OFF
            flight_list.append(flight_node)
        status_row_list = data.xpath('//table[@id="_etrkawbdetails_WAR_etrkportlet_statusHistoryTableContainer"]/tbody/tr')
        for status_row in status_row_list:
            status_col_list = status_row.xpath('td')
            flight_content = status_col_list[3].xpath('.//text()').get()
            if flight_content is None or flight_content.strip() == "":
                continue
            flight_number = common_util.formatter_html_text(flight_content)
            actual_time_content = status_col_list[6].xpath('text()').get()
            actual_datetime = common_util.convert_standard_datetime(actual_time_content,"%d %b %y / %H:%M")
            plan_time_content = status_col_list[7].xpath('text()').get()
            plan_datetime = common_util.convert_standard_datetime(plan_time_content,"%d %b %y / %H:%M")
            status_content = status_col_list[0].xpath('text()').get()
            if status_content is None or status_content.strip() == "":
                continue
            if status_content.strip() == "ARR":
                for flight in flight_list:
                    if flight.flight_number == flight_number:
                        flight.flight_eta = plan_datetime
                        if actual_datetime is not None:
                            flight.flight_ata = actual_datetime
                            if flight.flight_status != FlightStatusEnum.ARRIVED:
                                flight.flight_status = FlightStatusEnum.ARRIVED
            elif status_content.strip() == "DEP":
                for flight in flight_list:
                    if flight.flight_number == flight_number:
                        flight.flight_etd = plan_datetime
                        if actual_datetime is not None:
                            flight.flight_atd = actual_datetime
                            if flight.flight_status == FlightStatusEnum.UN_TAKE_OFF:
                                flight.flight_status = FlightStatusEnum.TAKE_OFF
        return flight_list

    def pick_event_list(self, data) -> List[AwbCargoEvent]:
        event_list: List[AwbCargoEvent] = []
        status_row_list = data.xpath(
            '//table[@id="_etrkawbdetails_WAR_etrkportlet_statusHistoryTableContainer"]/tbody/tr')
        for status_row in status_row_list:
            air_event = copy.deepcopy(AwbCargoEvent())
            status_col_list = status_row.xpath('td')
            actual_time_content = status_col_list[6].xpath('.//text()').get()
            if actual_time_content is not None and actual_time_content != "":
                air_event.event_time = common_util.convert_standard_datetime(common_util.formatter_html_text(actual_time_content), "%d %b %y / %H:%M")
            else:
                plan_time_content = status_col_list[7].xpath('.//text()').get()
                if plan_time_content is None or plan_time_content.strip() == "":
                    continue
                plan_time = datetime.strptime(common_util.formatter_html_text(plan_time_content), "%d %b %y / %H:%M")
                if plan_time < datetime.now() - timedelta(days=3):
                    air_event.event_time = plan_time.strftime(settings.STANDARD_DATETIME_FORMATTER)
                else:
                    continue
            status_content = status_col_list[0].xpath('text()').get()
            if status_content is not None and status_content.strip() != "":
                air_event.status_code = status_content.strip()
            air_event.event_desc = status_col_list[1].xpath('text()').get()
            station_content = status_col_list[2].xpath('.//text()').get()
            if station_content is not None and station_content.strip() != "":
                air_event.station = status_col_list[2].xpath('.//text()').get().split('(')[0]
            flight_content = status_col_list[3].xpath('.//text()').getall()
            if flight_content is not None and len(flight_content) > 0:
                air_event.flight_desc = common_util.formatter_html_text("".join(flight_content))
            pieces_weight = common_util.formatter_html_text(status_col_list[4].xpath('text()').get())
            if pieces_weight is None or pieces_weight == "":
                pieces_weight = status_col_list[5].xpath('text()').get()
            if pieces_weight is not None and pieces_weight != "" and pieces_weight.find("/") != -1:
                pieces = pieces_weight.split("/")[0].strip()
                if pieces.isnumeric():
                    air_event.pieces = int(pieces)
                air_event.weight = pieces_weight.split("/")[1].strip()
            event_list.append(air_event)
        return event_list

